package com.san.metadata.controller;

import java.util.List;
import java.util.Map;

import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.san.base.controller.BaseController;
import com.san.common.annotation.Log;
import com.san.common.utils.Constant;
import com.san.common.utils.PageUtils;
import com.san.common.utils.Query;
import com.san.common.utils.R;
import com.san.metadata.domain.DataSourceDO;
import com.san.metadata.domain.ManageColumnsDO;
import com.san.metadata.domain.ManageTableDO;
import com.san.metadata.domain.TechnicalColumnsDO;
import com.san.metadata.domain.TechnicalTableDO;
import com.san.metadata.service.DataSourceService;
import com.san.metadata.service.ManageMetadataService;
import com.san.metadata.service.TechnicalMetadataService;
import com.san.metadata.vo.ManageColumnsVO;

/**
 * 管理元数据业务控制器
 * 
 * @author hulp
 *
 */
@RequestMapping("/md/manage")
@Controller
public class ManageMetadataController extends BaseController {

	private static final Logger logger = LoggerFactory.getLogger(ManageMetadataController.class);

	/**
	 * 本功能地址前缀
	 */
	private static final String PREFIX = "metadata/manage";

	@Autowired
	DataSourceService dataSourceService;

	@Autowired
	ManageMetadataService manageMetadataService;

	@Autowired
	TechnicalMetadataService technicalMetadataService;

	/**
	 * 管理元数据列表页
	 * 
	 * @param model
	 * @return
	 */

	@RequiresPermissions("md:manage:view")
	@GetMapping("")
	String manage(Model model) {
		return PREFIX + "/view";
	}

	/**
	 * 管理元数据列表接口
	 * 
	 * @param params
	 * @return
	 */
	@RequiresPermissions("md:manage:view")
	@GetMapping("/list")
	@ResponseBody
	public PageUtils findListmanage(@RequestParam Map<String, Object> params) {
		PageUtils pageUtils = null;
		try {
			Query query = new Query(params);
			pageUtils = manageMetadataService.list(query);
		} catch (Exception e) {
			logger.error("分页获取管理元数据列表出错", e);
		}

		return pageUtils;
	}

	/**
	 * 查询管理元数据的表
	 * 
	 * @param params
	 * @return
	 */
	@RequiresPermissions("md:manage:view")
	@GetMapping("/listAllTechnicalTable")
	@ResponseBody
	public List<TechnicalTableDO> listAllTechnicalTable(@RequestParam Map<String, Object> params) {
		List<TechnicalTableDO> list = null;
		try {
			params.put("createFlag", new Long(0));
			Query query = new Query(params);
			list = technicalMetadataService.allTechnicalTable(query);
		} catch (Exception e) {
			logger.error("分页获取管理元数据列表出错", e);
		}

		return list;
	}

	/**
	 * 查询管理元数据表下的所有字段
	 * 
	 * @param params
	 * @return
	 */
	@RequiresPermissions("md:manage:view")
	@GetMapping("/allColumns/{tableId}")
	@ResponseBody
	public PageUtils allColumns(@PathVariable("tableId") Long tableId) {
		ManageTableDO manageTableDO = null;
		try {
			manageTableDO = manageMetadataService.getById(tableId);
		} catch (Exception e1) {
			logger.error("获取管理元数据出错", e1);
		}
		PageUtils pageUtils = null;
		if (manageTableDO.getCreateFlag() == Constant.CREATE_FLAG_YES) { // 已建表则查询管理元数据字段信息表
			try {
				List<ManageColumnsDO> list = manageMetadataService.allManageColumns(tableId);
				pageUtils = new PageUtils(list, list.size());
			} catch (Exception e) {
				logger.error("获取管理元数据字段关系表信息出错", e);
			}
		} else { // 查询技术元数据表
			try {
				List<TechnicalColumnsDO> list = technicalMetadataService
						.allTechnicalColumns(manageTableDO.getSourceTableId());
				pageUtils = new PageUtils(list, list.size());
			} catch (Exception e) {
				logger.error("分页获取管理元数据列表出错", e);
			}
		}
		return pageUtils;
	}

	/**
	 * 跳转新增管理元数据-手动建表页面
	 * 
	 * @return
	 */
	@GetMapping("/addByHand")
	@Log("新增管理元数据——手动")
	@RequiresPermissions("md:manage:add")
	String addByHand() {
		return PREFIX + "/addByHand";
	}

	/**
	 * 跳转新增管理元数据-交换建表页面
	 * 
	 * @return
	 */
	@GetMapping("/addByExchange")
	@Log("新增管理元数据——交换")
	@RequiresPermissions("md:manage:add")
	String addByExchange() {
		return PREFIX + "/addByExchange";
	}

	/**
	 * 保存管理元数据
	 * 
	 * @param manageTableDO
	 * @return
	 */
	@RequiresPermissions("md:manage:add")
	@Log("保存管理元数据")
	@PostMapping("/save")
	@ResponseBody
	R save(ManageTableDO manageTableDO) {
		manageTableDO.setCreateUserId(this.getUserId());
		manageTableDO.setTargetTableName("M_"+manageTableDO.getTargetTableName());
		try {
			if (manageMetadataService.save(manageTableDO) > 0) {
				return R.ok();
			}
		} catch (Exception e) {
			logger.error("保存管理元数据出错", e);
			return R.error();
		}
		return R.error();
	}

	/**
	 * 编辑管理元数据
	 * 
	 * @param model
	 * @param tableId 管理元数据ID
	 * @return
	 */
	@GetMapping("/edit/{tableId}")
	@Log("编辑管理元数据")
	@RequiresPermissions("md:manage:edit")
	String edit(Model model, @PathVariable("tableId") Long tableId) {
		ManageTableDO tmdo = null;
		try {
			tmdo = manageMetadataService.getById(tableId);
		} catch (Exception e) {
			logger.error("获取管理元数据出错", e);
		}
		model.addAttribute("manageMetadata", tmdo);
		return PREFIX + "/edit";
	}

	/**
	 * 更新管理元数据
	 * 
	 * @param manageTableDO
	 * @return
	 */
	@PostMapping("/doEdit")
	@Log("更新管理元数据")
	@RequiresPermissions("md:manage:edit")
	@ResponseBody
	R doEdit(ManageTableDO manageTableDO) {
		manageTableDO.setUpdateUserId(this.getUserId());
		try {
			if (manageMetadataService.doEdit(manageTableDO) > 0) {
				return R.ok();
			}
		} catch (Exception e) {
			logger.error("更新管理元数据出错", e);
			return R.error();
		}
		return R.error();
	}

	/**
	 * 删除管理元数据
	 * 
	 * @param id 管理元数据ID
	 * @return
	 */
	@PostMapping("/remove")
	@Log("删除管理元数据")
	@RequiresPermissions("md:manage:remove")
	@ResponseBody
	R remove(Long id) {
		try {
			if (manageMetadataService.remove(id) > 0) {
				return R.ok();
			}
		} catch (Exception e) {
			logger.error("删除管理元数据出错", e);
			return R.error();
		}
		return R.error("删除管理元数据失败");
	}

	/**
	 * 批量删除管理元数据
	 * 
	 * @param ids 管理元数据ID集合
	 * @return
	 */
	@PostMapping("/batchRemove")
	@Log("批量删除管理元数据")
	@RequiresPermissions("md:manage:batchRemove")
	@ResponseBody
	R batchRemove(@RequestParam("ids[]") Long[] ids) {
		int r = 0;
		try {
			r = manageMetadataService.batchRemove(ids);
		} catch (Exception e) {
			logger.error("批量删除管理元数据出错", e);
			return R.error();
		}
		if (r > 0) {
			return R.ok();
		}
		return R.error("批量删除管理元数据失败");
	}

	/**
	 * 编辑管理元数据表字段
	 * 
	 * @param model
	 * @param tableId 管理元数据表ID
	 * @return
	 */
	@GetMapping("/editColumns/{tableId}")
	@Log("编辑管理元数据表字段")
	@RequiresPermissions("md:manage:view")
	String editColumns(Model model, @PathVariable("tableId") Long tableId) {
		model.addAttribute("tableId", tableId);
		ManageTableDO manageTableDO = null;
		try {
			manageTableDO = manageMetadataService.getById(tableId);
		} catch (Exception e) {
			logger.error("获取管理元数据信息出错", e);
		}
		model.addAttribute("manageTableDO", manageTableDO);
		if (manageTableDO.getCreateFlag() == Constant.CREATE_FLAG_YES) {
			return PREFIX + "/viewColumns";
		}
		if (manageTableDO.getImportType() == Constant.IMPORT_TYPE_HAND) {
			return PREFIX + "/editColumnsByHand";
		}
		return PREFIX + "/editColumns";
	}

	/**
	 * 批量添加管理元数据字段
	 * 
	 * @param tableId             管理元数据表ID
	 * @param manageColumnsVOList 管理元数据字段信息List
	 * @return
	 */
	@PostMapping("/batchColumnsAdd/{tableId}")
	@Log("批量添加管理元数据字段")
	@RequiresPermissions("md:manage:batchRemove")
	@ResponseBody
	@Transactional
	R batchColumnsAdd(@PathVariable("tableId") Long tableId, @RequestBody List<ManageColumnsVO> manageColumnsVOList) {
		ManageTableDO manageTableDO = null;
		try {
			manageTableDO = manageMetadataService.getById(tableId);
		} catch (Exception e) {
			logger.error("获取管理元数据表信息出错", e);
			return R.error();
		}
		for (ManageColumnsVO i : manageColumnsVOList) {
			i.setTableId(manageTableDO.getTableId());
			i.setCreateUserId(this.getUserId());
		}
		DataSourceDO targetDataSourceDO = null; // 目标数据源DO
		try {
			targetDataSourceDO = (DataSourceDO) dataSourceService.getById(manageTableDO.getTargetSourceId());
		} catch (Exception e) {
			logger.error("获取数据源信息出错", e);
		}

		int SourceType = Constant.SOURCE_TYPE_MYSQL; // 源数据源

		boolean flag = manageMetadataService.saveTable(SourceType, tableId, targetDataSourceDO, manageColumnsVOList);
		if (flag) {
			return R.ok();
		}
		return R.error();
	}

	/**
	 * 批量修改管理元数据字段标记
	 * 
	 * @param tableId             管理元数据表ID
	 * @param ManageColumnsVOList 管理元数据字段信息List
	 * @return
	 */
	@PostMapping("/batchColumnsUpdate/{tableId}")
	@Log("批量修改管理元数据字段标记")
	@RequiresPermissions("md:technical:add")
	@ResponseBody
	@Transactional
	R batchColumnsUpdate(@PathVariable("tableId") Long tableId,
			@RequestBody List<ManageColumnsVO> ManageColumnsVOList) {
		int r = 0;
		try {
			r = manageMetadataService.batchColumnsUpdate(ManageColumnsVOList);
		} catch (Exception e) {
			logger.error("批量修改管理元数据字段标记失败", e);
			return R.error();
		}
		if (r > 0) {
			// TODO : 全量更新去重字段信息
			return R.ok();
		}
		return R.error("批量修改管理元数据字段标记失败");
	}

}
